package com.wy.restlet;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jst.j2ee.common.CommonFactory;
import org.eclipse.jst.j2ee.common.ParamValue;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
import org.eclipse.jst.j2ee.webapplication.InitParam;
import org.eclipse.jst.j2ee.webapplication.Servlet;
import org.eclipse.jst.j2ee.webapplication.ServletMapping;
import org.eclipse.jst.j2ee.webapplication.ServletType;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.j2ee.webapplication.WebapplicationFactory;

import com.wy.base.AbstractWizard;

@SuppressWarnings("restriction")
public class RestletWebserviceWizard extends AbstractWizard {

	private String[] restletJars;

	private String downloadSite = "http://karthy.me/repository/jars/";

	private String restletClass = "org.restlet.ext.servlet.ServerServlet";

	public RestletWebserviceWizard() {
		super();
		setNeedsProgressMonitor(true);
	}

	protected void handlerProperties(Properties props) {
		this.restletClass = props.getProperty("restlet.class", restletClass);
		this.downloadSite = (props.getProperty("download.site") + "restlet/");
		StringTokenizer st = new StringTokenizer(props.getProperty("restlet.jars"), ",");
		String[] temp = new String[st.countTokens()];
		for (int i = 0; st.hasMoreTokens(); i++) {
			temp[i] = st.nextToken();
		}
		this.restletJars = temp;
	}

	/**
	 * Adding the page to the wizard.
	 */
	@Override
	public void addPages() {
		// page = new RestletWebservicePage(selection);
		// addPage(page);
		setPage(new RestletWebservicePage(this.getSelection()));
		addPage(getPage());
	}

	@Override
	public boolean performFinish() {
		return super.performFinish("/templates/restlet.template");
	}

	/**
	 * The worker method. It will find the container, create the file if missing or
	 * just replace its contents, and open the editor on the newly created file.
	 * 
	 * @throws Exception
	 */
	public void doFinish(String containerName, String fileName, String packageName, IProgressMonitor monitor,
			String templateUri) throws Exception {
		// create a sample file
		monitor.beginTask("Creating " + fileName, 2);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IResource resource = root.findMember(new Path(containerName));
		if (!resource.exists() || !(resource instanceof IContainer)) {
			throwCoreException("Container \"" + containerName + "\" does not exist.");
		}

		IContainer container = (IContainer) resource;
		IJavaProject project = (IJavaProject) container.getProject().getNature("org.eclipse.jdt.core.javanature");
		IPackageFragment ipackage =
				project.getAllPackageFragmentRoots()[0].createPackageFragment(packageName, false, monitor);
		String contents = loadTemplate(containerName, templateUri);
		ipackage.createCompilationUnit(fileName + ".java", contents, false, monitor);
		contents = getRestletApplicationClass(containerName);
		ipackage.createCompilationUnit(fileName + "Application" + ".java", contents, false, monitor);
		monitor.worked(1);
	}

	private String getRestletApplicationClass(String containerName) throws Exception {
		StringBuffer sb = new StringBuffer();
		BufferedReader reader;
		InputStream input = this.getClass().getResourceAsStream("/templates/restletapplication.template");
		reader = new BufferedReader(new InputStreamReader(input));
		String line = null;
		while ((line = reader.readLine()) != null) {
			System.out.println(line);
			line = line.replaceAll("#classname", fileName);
			line = line.replaceAll("#package", packageName);
			boolean skip = false;
			line = line.replaceAll("#projectname", containerName);
			if (!skip) {
				sb.append(line);
				sb.append("\n");
			}
		}
		reader.close();
		reader.close();
		return sb.toString();
	}

	@SuppressWarnings({ "unchecked", "unused" })
	public void addServlet(String containerName) throws Exception {
		loadProperties();
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IResource resource = root.findMember(new Path(containerName));
		IContainer container = (IContainer) resource;
		IJavaProject project = (IJavaProject) container.getProject().getNature("org.eclipse.jdt.core.javanature");
		IProject ip = (IProject) project.getCorrespondingResource();
		Servlet servlet = null;
		EList<Servlet> servlets;
		boolean exists;
		WebArtifactEdit artifact = WebArtifactEdit.getWebArtifactEditForWrite(ip);
		WebApp webApp = artifact.getWebApp();
		exists = false;
		servlets = webApp.getServlets();
		Iterator<Servlet> iterator = servlets.iterator();
		while (iterator.hasNext()) {
			Servlet ser = iterator.next();
			if (ser.getServletClass().getJavaName().equals(this.restletClass)) {
				exists = true;
				break;
			}
		}
		if (!exists) {
			servlet = WebapplicationFactory.eINSTANCE.createServlet();
			servlet.setServletName("RestletServletAdaptor");
			ServletType type = WebapplicationFactory.eINSTANCE.createServletType();
			type.setClassName(restletClass);
			servlet.setWebType(type);
			servlet.setLoadOnStartup(Integer.valueOf(1));
			if (webApp.getJ2EEVersionID() >= J2EEVersionConstants.J2EE_1_4_ID) {
				ParamValue param = CommonFactory.eINSTANCE.createParamValue();
				param.setName("org.restlet.application");
				param.setValue(packageName + "." + fileName + "Application");
				servlet.getInitParams().add(param);
			} else {
				InitParam initParam = WebapplicationFactory.eINSTANCE.createInitParam();
				initParam.setParamName("org.restlet.application");
				initParam.setParamValue(packageName + "." + fileName + "Application");
				servlet.getInitParams().add(initParam);
			}
			webApp.getServlets().add(servlet);
			ServletMapping mapping = WebapplicationFactory.eINSTANCE.createServletMapping();
			mapping.setServlet(servlet);
			mapping.setUrlPattern("/" + "rs" + "/*");
			webApp.getServletMappings().add(mapping);
		}
		artifact.saveIfNecessary(null);
		artifact.dispose();
		IFolder dir = getWebInfLibDir(ip);
		if (dir.exists()) {
			int len = this.restletJars.length;
			for (int i = 0; i < len; i++) {
				String jar = restletJars[i];
				if (!dir.getFile(jar).exists()) {
					try {
						int split = jar.lastIndexOf('-');
						String folder = jar.substring(0, split) + ".jar/";
						dir.getFile(jar).create(new URL(this.downloadSite + jar).openStream(), false, null);
					} catch (Exception e) {
						System.err.println(e.getMessage());
					}
				}
			}
		}
	}
}